/** FASSIT (Forms of Selective Attention in Intelligent Transportation Systems)
 * Computational Creativity and Digital Media
 * Cognitive and Media Systems Group
 * Centre for Informatics and Systems of the University of Coimbra (CISUC)
 *
 * Copyright (c) 2010-2013 University of Coimbra, Portugal
 * All rights reserved.
 */
package agent.Knowledge;

import java.util.ArrayList;
import java.util.HashMap;

import poi.Info.POI;
import poi.Info.POIwithSAMetrics;
import poi.Surprise.*;
import poi.SurpriseCalculator.SurpriseCalculatorForPOI;
import poi.Uncertainty.*;
import poi.UncertaintyCalculator.UncertaintyCalculatorForPOI;
import agent.Context.Context;
import agent.DBManager.AgentDBManager;
import agent.Metrics.Surprise.PastSurpriseValues;
import agent.Metrics.Uncertainty.PastUncertaintyValues;

/**
 * This class is used as an Interface to the Agent methods. Allows the Agent to
 * store and retrieve information from the database. It also allows to convert a
 * POI to a POI with Selective Attention Metrics.
 * 
 * @author Hernani Costa
 * @version 0.2 date: 11/02/2013
 */
public class Agent {
	private AgentPastKnowledgeAboutSurprise agentPastKnowledgeAboutSurprise;
	private AgentPastKnowledgeAboutUncertainty agentPastKnowledgeAboutUncertainty;
	private AgentDBManager dbManager;

	public Agent() {
		dbManager = new AgentDBManager();
	}

	/**
	 * ------------------------------------------------------------------------
	 * Allows the agent to retrieve the agent's past knowledge about Surprise
	 * ------------------------------------------------------------------------
	 * 
	 * @param context
	 *            - Context
	 * @return retrieves the agent's past knowledge about Surprise
	 */
	public Surprise getAgentPastKnowledgeAboutSurprise(
			Context context) {
		agentPastKnowledgeAboutSurprise = new AgentPastKnowledgeAboutSurprise(
				context);
		return agentPastKnowledgeAboutSurprise.getAgentPastKnowledgeAboutSurprise();
	}

	public Surprise getAgentPastKnowledgeAboutSurprise(
			String email, String goal) {
		agentPastKnowledgeAboutSurprise = new AgentPastKnowledgeAboutSurprise(
				email, goal);
		return agentPastKnowledgeAboutSurprise.getAgentPastKnowledgeAboutSurprise();
	}
	
	/**
	 * ------------------------------------------------------------------------
	 * Allows the agent to retrieve the agent's past knowledge about Uncertainty
	 * ------------------------------------------------------------------------
	 * 
	 * @param context
	 *            - Context
	 * @return retrieves the agent's past knowledge about Uncertainty
	 */
	public Uncertainty getAgentPastKnowledgeAboutUncertainty(
			Context context) {
		agentPastKnowledgeAboutUncertainty = new AgentPastKnowledgeAboutUncertainty(
				context);
		return agentPastKnowledgeAboutUncertainty.getAgentPastKnowledgeAboutUncertainty();
	}
	
	public Uncertainty getAgentPastKnowledgeAboutUncertainty(String email, String goal) {
		agentPastKnowledgeAboutUncertainty = new AgentPastKnowledgeAboutUncertainty(
				email, goal);
		return agentPastKnowledgeAboutUncertainty.getAgentPastKnowledgeAboutUncertainty();
	}
	
	/**
	 * ------------------------------------------------------------------------
	 * Only used by the class Train. Deletes all the Agent's Knowledge
	 * ------------------------------------------------------------------------
	 */
	public void deleteAgentKnowledge() {
		dbManager.deleteAgentKnowledge();
	}

	/**
	 * ------------------------------------------------------------------------
	 * Stores all the POIs visited by the Agent
	 * ------------------------------------------------------------------------
	 * 
	 * @param pois
	 *            - POIs visited
	 * @param context
	 *            - context when the Agent visited these POIs
	 */
	public void savePOIs(ArrayList<POI> pois, Context context) {
		dbManager.savePOIs(pois, context);
	}

	/**
	 * ------------------------------------------------------------------------
	 * Saves the Selective Attention values of a specific POI, i.e., the Surprise and Uncertainty values
	 * for all the parameters (Price, DaysOff and Schedule)
	 * ------------------------------------------------------------------------
	 * 
	 * @param poiWithSAMetrics
	 *            - POI with the Selective Attention values
	 * @param context
	 *            - the Agent's context
	 */
	public void saveSAValues(POIwithSAMetrics poiWithSAMetrics,
			Context context) {

		dbManager.saveSelectiveAttentionValues(poiWithSAMetrics, context);
	}

	
	/**
	 * ------------------------------------------------------------------------
	 * Returns all Agent's Knowledge for the surprise values already visited by
	 * the Agent, considering a specific Context (Goal)
	 * ------------------------------------------------------------------------
	 * 
	 * @param context
	 *            - Context
	 * @return Surprise values the Agent has
	 */
	public PastSurpriseValues getSurpriseValuesForGoal(Context context) {
		return dbManager.getSurpriseValuesForGoal(context);
	}
	
	/**
	 * ------------------------------------------------------------------------
	 * Returns all Agent's Knowledge for the uncertainty values already visited by
	 * the Agent, considering a specific Context (Goal)
	 * ------------------------------------------------------------------------
	 * 
	 * @param context
	 *            - Context
	 * @return Uncertainty values the Agent has
	 */
	public PastUncertaintyValues getUncertaintyValuesForGoal(Context context) {
		return dbManager.getUncertaintyValuesForGoal(context);
	}

	/**
	 * This method creates the new object POIwithSAMetrics. It converts
	 * automatically a POI to a POIwithSAMetrics
	 * 
	 * @param poi
	 *            - the POI to be converted
	 * @return {@link POIwithSAMetrics} - the resulted POI with Selective Attention Metrics
	 */
	public POIwithSAMetrics getSAValuesForPOI(POI poi) {
		HashMap<Integer, POI> pois = new HashMap<Integer, POI>();
		pois.put(poi.getPoiID(), poi);
		
		SurpriseCalculatorForPOI surpriseCalculator = new SurpriseCalculatorForPOI(pois);
		UncertaintyCalculatorForPOI uncertaintyCalculator = new UncertaintyCalculatorForPOI(pois);
		
		HashMap<Integer, SurprisePrice> sPrice = surpriseCalculator
				.getPoiSurprisePrice();
		HashMap<Integer, SurpriseDaysOff> sDayOff = surpriseCalculator
				.getPoiSurpriseDayOff();
		HashMap<Integer, SurpriseSchedule> sSchedule = surpriseCalculator
				.getPoiSurpriseSchedule();
		
		HashMap<Integer, UncertaintyPrice> uPrice = uncertaintyCalculator
				.getPoiUncertaintyPrice();
		HashMap<Integer, UncertaintyDaysOff> uDayOff = uncertaintyCalculator.getPoiUncertaintyDayOff();
		HashMap<Integer, UncertaintySchedule> uSchedule = uncertaintyCalculator.getPoiUncertaintySchedule();
		

		POIwithSAMetrics poiSA = new POIwithSAMetrics(poi, sPrice.get(poi.getPoiID()), sDayOff.get(poi.getPoiID()), sSchedule.get(poi.getPoiID()),
				uPrice.get(poi.getPoiID()), uDayOff.get(poi.getPoiID()), uSchedule.get(poi.getPoiID())
				);
		return poiSA;
	}
}
